home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / ingres04.lzh / source / parser / format.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-18  |  7.1 KB  |  353 lines

  1. # include    <ingres.h>
  2. # include    <aux.h>
  3. # include    <tree.h>
  4. # include    <symbol.h>
  5. # include    "parser.h"
  6. # include    <errors.h>
  7.  
  8. /*
  9. **  FORMAT
  10. **    routine to compute the format of the result relation attributes
  11. **    it is called after ATTLOOKUP so the tuple defining the current
  12. **    attribute is already available.
  13. **    if the element is a function of more than one attribute, the result
  14. **    domain format is computed by the following rules:
  15. **        - no fcns allowed on character attributes
  16. **        - fcn of integer attribs is an integer fcn with
  17. **          length = MAX(length of all attributes)
  18. **        - fcn of floating point attribs is a floating point
  19. **          fcn with length = MIN(length of all attribs)
  20. **        - fcn of integer and floating attributes is a
  21. **          floating fcn with length = MIN(length of all floating
  22. **          attributes)
  23. **
  24. **    Trace Flags:
  25. **        Format ~~ 52.0, 52.1
  26. */
  27.  
  28. format(result1)
  29. QTREE    *result1;
  30. {
  31.     register char        rfrmt;
  32.     register char        rfrml;
  33.     register QTREE        *result;
  34.     struct constop        *cpt;
  35.  
  36.     extern struct out_arg    Out_arg;
  37.     extern struct constop    Coptab[];
  38.     extern char        Trfrml;
  39.     extern char        Trfrmt;
  40.     extern int        Qlflag;
  41.  
  42. # ifdef    xPTR2
  43.     tTfp(52, 0, "format:.\n");
  44. # endif
  45.  
  46.     result = result1;
  47.     switch (result->sym.type)
  48.     {
  49.       case VAR:
  50.         rfrmt = result->sym.value.sym_var.varfrmt;
  51.         rfrml = result->sym.value.sym_var.varfrml;
  52.               break;
  53.  
  54.       case AOP:
  55.         switch (result->sym.value.sym_op.opno)
  56.         {
  57.           case opAVG:
  58.           case opAVGU:
  59.             rfrmt = FLOAT;
  60.             rfrml = 8;
  61.             if (result->sym.value.sym_op.agfrmt == CHAR)
  62.                 /* character domain not allowed in these aggs */
  63.                 par_error(AVGTYPE, WARN, 0);
  64.             break;
  65.  
  66.           case opCOUNT:
  67.           case opCOUNTU:
  68.             rfrmt = INT;
  69.             rfrml = 4;
  70.             break;
  71.  
  72.           case opANY:
  73.             rfrmt = INT;
  74.             rfrml = 2;
  75.             break;
  76.  
  77.           case opSUM:
  78.           case opSUMU:
  79.             rfrmt = result->sym.value.sym_op.agfrmt;
  80.             rfrml = result->sym.value.sym_op.agfrml;
  81.             if (rfrmt == CHAR)
  82.                 /* no char domains for these aggs */
  83.                 par_error(SUMTYPE, WARN, 0);
  84.             break;
  85.  
  86.           default:
  87.             rfrmt = result->sym.value.sym_op.agfrmt;
  88.             rfrml = result->sym.value.sym_op.agfrml;
  89.             break;
  90.         }
  91.         break;
  92.  
  93.       case AGHEAD:
  94.         /*
  95.         ** can get format info from the AOP node because
  96.         ** it already has format info computed
  97.         */
  98.         if (result->left->sym.type == AOP)
  99.         {
  100.             /* no by-list */
  101.             rfrmt = result->left->sym.value.sym_op.opfrmt;
  102.             rfrml = result->left->sym.value.sym_op.opfrml;
  103.         }
  104.         else
  105.         {
  106.             /* skip over by-list */
  107.             rfrmt = result->left->right->sym.value.sym_resdom.resfrmt;
  108.             rfrml = result->left->right->sym.value.sym_resdom.resfrml;
  109.         }
  110.         break;
  111.  
  112.       case RESDOM:
  113.         format(result->right);
  114.         return;
  115.  
  116.       case INT:
  117.       case FLOAT:
  118.       case CHAR:
  119.         rfrmt = result->sym.type;
  120.         rfrml = result->sym.len;
  121.         break;
  122.  
  123.       case COP:
  124.         for (cpt = Coptab; cpt->copname; cpt++)
  125.         {
  126.             if (result->sym.value.sym_op.opno == cpt->copnum)
  127.             {
  128.                 rfrmt = cpt->coptype;
  129.                 rfrml = cpt->coplen;
  130.                 break;
  131.             }
  132.         }
  133.         if (!cpt->copname)
  134.             syserr("bad cop in format(%d)", result->sym.value.sym_op.opno);
  135.         break;
  136.  
  137.       case UOP:
  138.         switch (result->sym.value.sym_op.opno)
  139.         {
  140.           case opATAN:
  141.           case opCOS:
  142.           case opLOG:
  143.           case opSIN:
  144.           case opSQRT:
  145.           case opEXP:
  146.             format(result->left);
  147.             if (Trfrmt == CHAR)
  148.                 /*
  149.                 ** no character expr in FOP
  150.                 ** if more ops are added, must change error message */
  151.                 par_error(FOPTYPE, WARN, 0);
  152.  
  153.           case opFLOAT8:
  154.             /* float8 is type conversion and can have char values */
  155.             rfrmt = FLOAT;
  156.             rfrml = 8;
  157.             break;
  158.  
  159.           case opFLOAT4:
  160.             rfrmt = FLOAT;
  161.             rfrml = 4;
  162.             break;
  163.  
  164.           case opINT1:
  165.             rfrmt = INT;
  166.             rfrml = 1;
  167.             break;
  168.  
  169.           case opINT2:
  170.             rfrmt = INT;
  171.             rfrml = 2;
  172.             break;
  173.  
  174.           case opINT4:
  175.             rfrmt = INT;
  176.             rfrml = 4;
  177.             break;
  178.  
  179.           case opASCII:
  180.             format(result->left);
  181.             rfrmt = CHAR;
  182.             rfrml = Trfrml;
  183.             if (Trfrmt == INT)
  184.             {
  185.                 if (Trfrml == 2)
  186.                     rfrml = Out_arg.i2width;
  187.                 else if (Trfrml == 4)
  188.                     rfrml = Out_arg.i4width;
  189.                 else if (Trfrml == 1)
  190.                     rfrml = Out_arg.i1width;
  191.                 else
  192.                     syserr("bad length %d for INT", Trfrml);
  193.                 break;
  194.             }
  195.             if (Trfrmt == FLOAT)
  196.             {
  197.                 if (Trfrml == 8)
  198.                     rfrml = Out_arg.f8width;
  199.                 else if (Trfrml == 4)
  200.                     rfrml = Out_arg.f4width;
  201.                 else
  202.                     syserr("bad length %d for FLOAT", Trfrml);
  203.                 break;
  204.             }
  205.             if (Trfrmt == CHAR)
  206.                 break;
  207.             syserr("bad frmt in opASCII %d", Trfrmt);
  208.  
  209.           case opNOT:
  210.             if (!Qlflag)
  211.                 syserr("opNOT in targ list");
  212.             return;
  213.  
  214.           case opMINUS:
  215.           case opPLUS:
  216.             format(result->right);
  217.             if (Trfrmt == CHAR)
  218.                 /* no chars for these unary ops */
  219.                 par_error(UOPTYPE, WARN, 0);
  220.             return;
  221.  
  222.           case opABS:
  223.             format(result->left);
  224.             if (Trfrmt == CHAR)
  225.                 /* no char values in fcn */
  226.                 par_error(FOPTYPE, WARN, 0);
  227.             return;
  228.  
  229.           default:
  230.             syserr("bad UOP in format %d", result->sym.value.sym_op.opno);
  231.         }
  232.         break;
  233.  
  234.       case BOP:
  235.         switch (result->sym.value.sym_op.opno)
  236.         {
  237.  
  238.           case opEQ:
  239.           case opNE:
  240.           case opLT:
  241.           case opLE:
  242.           case opGT:
  243.           case opGE:
  244.             if (!Qlflag)
  245.                 syserr("LBOP in targ list");
  246.             format(result->right);
  247.             rfrmt = Trfrmt;
  248.             format(result->left);
  249.             if ((rfrmt == CHAR) != (Trfrmt == CHAR))
  250.                 /* type conflict on relational operator */
  251.                 par_error(RELTYPE, WARN, 0);
  252.             return;
  253.  
  254.           case opADD:
  255.           case opSUB:
  256.             format(result->left);
  257.             rfrmt = Trfrmt;
  258.             rfrml = Trfrml;
  259.             format(result->right);
  260.             if (rfrmt == FLOAT || Trfrmt == FLOAT)
  261.             {
  262.                 if (rfrmt == FLOAT && Trfrmt == FLOAT)
  263.                 {
  264.                     if (Trfrml < rfrml)
  265.                         rfrml = Trfrml;
  266.                 }
  267.                 else if (Trfrmt == FLOAT)
  268.                     rfrml = Trfrml;
  269.                 rfrmt = FLOAT;
  270.             }
  271.             else
  272.                 if (Trfrml > rfrml)
  273.                     rfrml = Trfrml;
  274.             break;
  275.  
  276.           case opMUL:
  277.           case opDIV:
  278.             format(result->left);
  279.             rfrmt = Trfrmt;
  280.             rfrml = Trfrml;
  281.             format(result->right);
  282.             if ((rfrmt == CHAR || Trfrmt == CHAR))
  283.                 par_error(NUMTYPE, WARN, 0);
  284.             if (rfrmt == FLOAT || Trfrmt == FLOAT)
  285.             {
  286.                 if (rfrmt == FLOAT && Trfrmt == FLOAT)
  287.                 {
  288.                     if (Trfrml < rfrml)
  289.                         rfrml = Trfrml;
  290.                 }
  291.                 else if (Trfrmt == FLOAT)
  292.                     rfrml = Trfrml;
  293.                 rfrmt = FLOAT;
  294.             }
  295.             else
  296.                 if (Trfrml > rfrml)
  297.                     rfrml = Trfrml;
  298.             break;
  299.  
  300.           case opMOD:
  301.             format(result->left);
  302.             rfrmt = Trfrmt;
  303.             rfrml = Trfrml;
  304.             format(result->right);
  305.             if (rfrmt != INT || Trfrmt != INT)
  306.                 /* mod operator not defined */
  307.                 par_error(MODTYPE, WARN, 0);
  308.             if (Trfrml > rfrml)
  309.                 rfrml = Trfrml;
  310.             break;
  311.  
  312.           case opPOW:
  313.             format(result->right);
  314.             rfrmt = Trfrmt;
  315.             rfrml = Trfrml;
  316.             format(result->left);
  317.             if (rfrmt == CHAR || Trfrmt == CHAR)
  318.                 /* no char values for pow */
  319.                 par_error(NUMTYPE, WARN, 0);
  320.             if ((rfrmt == FLOAT && rfrml == 4) || (Trfrmt == FLOAT && Trfrml == 4))
  321.             {
  322.                 rfrmt = FLOAT;
  323.                 rfrml = 4;
  324.             }
  325.             else
  326.             {
  327.                 rfrmt = FLOAT;
  328.                 rfrml = 8;
  329.             }
  330.             break;
  331.  
  332.           case opCONCAT:
  333.             format(result->left);
  334.             rfrmt = Trfrmt;
  335.             rfrml = Trfrml;
  336.             format(result->right);
  337.             if (rfrmt != CHAR || Trfrmt != CHAR)
  338.                 /* only character domains allowed */
  339.                 par_error(CONCATTYPE, WARN, 0);
  340.             rfrml += Trfrml;
  341.             break;
  342.  
  343.           default:
  344.             syserr("bad BOP in format %d", result->sym.value.sym_op.opno);
  345.         }
  346.     }
  347.     Trfrmt = rfrmt;
  348.     Trfrml = rfrml;
  349. # ifdef    xPTR2
  350.     tTfp(52, 2, "format>>: Trfrmt = %d, Trfrml = %d.\n", Trfrmt, Trfrml);
  351. # endif
  352. }
  353.